package com.cyx.fruit.mySSM.ssm;


import com.cyx.fruit.mySSM.IOC.BeanFactory;
import com.cyx.fruit.mySSM.IOC.ClassPathXmlApplicationContext;
import com.cyx.fruit.util.StringUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

@WebServlet("*.do")   //拦截所有以.do结尾的
public class DispatcherServlet extends ViewBaseServlet{
    private BeanFactory beanFactory;
    //解析xml文件
    public void init(){
        try {
            super.init();   //调用ViewBaseServlet的init
            beanFactory = new ClassPathXmlApplicationContext();
        } catch (ServletException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        String servletPath = req.getServletPath();
        servletPath = servletPath.substring(1);
        int index = servletPath.lastIndexOf(".do");
        servletPath = servletPath.substring(0,index);

        Object beanControllerObject = beanFactory.getBean(servletPath);   //通过fruit------->new FruitController

        String operation = req.getParameter("operation");
        if(StringUtil.isEmpty(operation)){
            //没有值默认为index
            operation = "index";
        }

        //add()对象，index()对象
        Method[] declaredMethods = beanControllerObject.getClass().getDeclaredMethods(); // 获取当前Class类对象所表示的类声明的所有方法
        for(Method method : declaredMethods){
            //遍历方法对象数组
            String methodName = method.getName();//获取当前方法对象的方法名
            if(methodName.equals(operation)){
                //操作和方法名同名，执行同名方法
                //请求
                Parameter[] parameters = method.getParameters();    //获取执行方法的形参数组,包括类型  名称
                Object[] parameterValues = new Object[parameters.length];//存入形参的实际参数

                for(int i = 0;i<parameters.length;i++){

                    Parameter parameter = parameters[i]; //当前形参

                    String name = parameter.getName(); //获取当前形参的名称--和请求参数同名
                    if(name.equals("req") || name.equals("request")){
                        parameterValues[i] = req;
                    }else if(name.equals("resp" )|| name.equals("response")){
                        parameterValues[i] = resp;
                    }else if(name.equals("session")){
                        parameterValues[i] = req.getSession();
                    }else{
                        //从请求里获取参数值
                        String parameterValueStr = req.getParameter(name);
                        String typeName = parameter.getType().getName(); //当前参数类型的全类名
                        Object parameterValueObj = (Object) parameterValueStr;//将字符串类型的参数值转为Object类型
                        if(parameterValueObj != null){
                            if(typeName.equals("java.lang.Integer")){//如果是Integer
                                parameterValueObj = Integer.parseInt(parameterValueStr);//变为整形
                            }
                        }
                        parameterValues[i] = parameterValueObj;
                    }
                }
                try {
                    method.setAccessible(true);
                    String returnStr = (String) method.invoke(beanControllerObject, parameterValues);//执行方法,需要请求参数
                    //returnStr     带不带redirect
                    if(returnStr.startsWith("redirect")){
                        //重定向
                        String redirctStr = returnStr.substring("redirect:".length());
                        resp.sendRedirect(redirctStr);
                    }else{
                        //转发
                        super.processTemplate(returnStr,req,resp);
                    }

                    return;
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        throw new RuntimeException("operation出错了");
    }
}
